Membre du Groupe : Ismael Mohamed 295465, Romain Pion 222525, Mathieu Guilbaud 223096 / Repo Github : https://github.com/MohamedXi/5rbig_project.git

Introduction

Ces données concernent les élèves de deux écoles publiques portugaises et ont été recueillies au cours de l’année scolaire 2005-2006. Nous étudierons toutes les variables et leurs interactions, en mettant l’accent sur les facteurs qui influent sur la réussite des élèves.

1 Préapartion de la data

1.1 Vérification des variables

Chargement des librairies

if(!require("ggplot2")){install.packages("ggplot2")}
if(!require("dplyr")){install.packages("dplyr")}
if(!require("ggwordcloud")){install.packages("ggwordcloud")}
if(!require("readxl")){install.packages("readxl")}
if(!require("factorplot")){install.packages("factorplot")}
if(!require("wordcloud2")){install.packages("wordcloud2")}
if(!require("readxl")){install.packages("readxl")}
if(!require("factorplot")){install.packages("factorplot")}
if(!require("pheatmap")){install.packages("pheatmap")}
if(!require("car")){install.packages("car")}
if(!require("factoextra")){install.packages("factoextra")}
if(!require("cluster")){install.packages("cluster")}
if(!require("tidyverse")){install.packages("tidyverse")}
library(tidyverse)
library(cluster)
library(factoextra)
library(ggplot2)
options(warn=-1)
library(dplyr)
library(readr)
library(psych)
library(ggwordcloud)
library(wordcloud2)
library(readxl)
library(factorplot)
library(pheatmap)
library(car)

Chargement des données.

mprbig <- read_excel("MP-5RBIG.xlsx")

Affichage des différentes variable;

head(mprbig)
summary(mprbig)
    school              sex                 age         address            famsize         
 Length:395         Length:395         Min.   :15.0   Length:395         Length:395        
 Class :character   Class :character   1st Qu.:16.0   Class :character   Class :character  
 Mode  :character   Mode  :character   Median :17.0   Mode  :character   Mode  :character  
                                       Mean   :16.7                                        
                                       3rd Qu.:18.0                                        
                                       Max.   :22.0                                        
   Pstatus               Medu            Fedu           Mjob               Fjob          
 Length:395         Min.   :0.000   Min.   :0.000   Length:395         Length:395        
 Class :character   1st Qu.:2.000   1st Qu.:2.000   Class :character   Class :character  
 Mode  :character   Median :3.000   Median :2.000   Mode  :character   Mode  :character  
                    Mean   :2.749   Mean   :2.522                                        
                    3rd Qu.:4.000   3rd Qu.:3.000                                        
                    Max.   :4.000   Max.   :4.000                                        
    reason            guardian           traveltime      studytime        failures     
 Length:395         Length:395         Min.   :1.000   Min.   :1.000   Min.   :0.0000  
 Class :character   Class :character   1st Qu.:1.000   1st Qu.:1.000   1st Qu.:0.0000  
 Mode  :character   Mode  :character   Median :1.000   Median :2.000   Median :0.0000  
                                       Mean   :1.448   Mean   :2.035   Mean   :0.3342  
                                       3rd Qu.:2.000   3rd Qu.:2.000   3rd Qu.:0.0000  
                                       Max.   :4.000   Max.   :4.000   Max.   :3.0000  
  schoolsup            famsup              paid            activities       
 Length:395         Length:395         Length:395         Length:395        
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
                                                                            
                                                                            
                                                                            
   nursery             higher            internet           romantic        
 Length:395         Length:395         Length:395         Length:395        
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
                                                                            
                                                                            
                                                                            
     famrel         freetime         goout            Dalc            Walc      
 Min.   :1.000   Min.   :1.000   Min.   :1.000   Min.   :1.000   Min.   :1.000  
 1st Qu.:4.000   1st Qu.:3.000   1st Qu.:2.000   1st Qu.:1.000   1st Qu.:1.000  
 Median :4.000   Median :3.000   Median :3.000   Median :1.000   Median :2.000  
 Mean   :3.944   Mean   :3.235   Mean   :3.109   Mean   :1.481   Mean   :2.291  
 3rd Qu.:5.000   3rd Qu.:4.000   3rd Qu.:4.000   3rd Qu.:2.000   3rd Qu.:3.000  
 Max.   :5.000   Max.   :5.000   Max.   :5.000   Max.   :5.000   Max.   :5.000  
     health         absences            G1              G2              G3       
 Min.   :1.000   Min.   : 0.000   Min.   : 3.00   Min.   : 0.00   Min.   : 0.00  
 1st Qu.:3.000   1st Qu.: 0.000   1st Qu.: 8.00   1st Qu.: 9.00   1st Qu.: 8.00  
 Median :4.000   Median : 4.000   Median :11.00   Median :11.00   Median :11.00  
 Mean   :3.554   Mean   : 5.709   Mean   :10.91   Mean   :10.71   Mean   :10.42  
 3rd Qu.:5.000   3rd Qu.: 8.000   3rd Qu.:13.00   3rd Qu.:13.00   3rd Qu.:14.00  
 Max.   :5.000   Max.   :75.000   Max.   :19.00   Max.   :19.00   Max.   :20.00  

Vérification s’il n’y a pas de valaure manquante

sum(is.na(mprbig))
[1] 0

1.2 Ajout de la variable finalResult

finalResult <- NULL
for (x in mprbig$G3) {
  if (x < 10 ) {
   finalResult <- c(finalResult,"fail")
  } else {
   finalResult <- c(finalResult,"pass")
  }
}
mprbig <- data.frame(mprbig,finalResult)
mprbig

1.3 Ajout de la variable academicGrade

academicGrade <- NULL
for (x in mprbig$G3) {
  if (x >= 16  ) {
   academicGrade <- c(academicGrade,"A")
  }
  if (x >= 14 && x < 16) {
   academicGrade <- c(academicGrade,"B")
  }
  if (x >= 12 && x < 14) {
   academicGrade <- c(academicGrade,"C")
  }
  if (x >= 10 && x < 12) {
   academicGrade <- c(academicGrade,"D")
  }
  if (x <= 9){
    academicGrade <- c(academicGrade,"E")
  }
}
mprbig <- data.frame(mprbig,academicGrade)
mprbig

2 Etude des variables catégorielles

2.1 Étudiez individuellement les principales variables catégorielles

Le genre La majorité des individus sont des femmes

ggplot(data=mprbig,aes(x=sex,fill=sex)) + geom_bar()

L’éducation de la mère La majorité des individus ont une mère avec un niveau d’étude élevé

ggplot(data=mprbig,aes(x=Medu,fill=Medu))+geom_bar()

L’éducation du père La majorité des individus ont un père ayant un niveau d’étude élevé

ggplot(data=mprbig,aes(x=Fedu,fill=Fedu))+geom_bar()

Le support pédagogique suplémentaire La majorité des individus n’ont pas de support pédagogique suplémentaire

ggplot(data=mprbig,aes(x=schoolsup,fill=schoolsup))+geom_bar()

Le soutien éducatif familial La majorité des individus ont un soutien éducatif familial

ggplot(data=mprbig,aes(x=famsup,fill=famsup))+geom_bar()

Les cours de mathématiques payant suplémentaire La majorité des individus ne suivent pas de cours de mathématiques payant suplémentaire

ggplot(data=mprbig,aes(x=paid,fill=paid))+geom_bar()

Nombre d’individus voulant suivre des études supérieurs La majorité des individus veulent suivre des études supérieurs

ggplot(data=mprbig,aes(x=higher,fill=higher))+geom_bar()

L’accès à internet à son domicile La majorité des individus ont accès à internet

ggplot(data=mprbig,aes(x=internet,fill=internet))+geom_bar()

Les admis La majorité des individus ont réussie leur examen

ggplot(data=mprbig,aes(x=finalResult,fill=finalResult))+geom_bar()

Le niveau obtenu à l’examen La majorité des individus ont obtenu le niveau E

ggplot(data=mprbig,aes(x=academicGrade,fill=academicGrade))+geom_bar()

2.2 Représente les associations entre des paires de variables catégorielles

Analyse du genre sur le support pédagogique suplémentaire Proportionellement, les femmes reçoivent plus souvent un support pédagogique suplémentaire que les hommes

ggplot(data=mprbig,aes(x=sex,fill=schoolsup))+geom_bar()

Analyse du genre sur l’aide éducatif familial Les hommes reçoivent plus souvent de l’aide éducatif familial que les femmes

ggplot(data=mprbig,aes(x=sex,fill=famsup))+geom_bar()

Analyse du genre sur l’envie de suivre des études supérieurs Les femmes ont majoritairement envie de faire des études supérieurs

ggplot(data=mprbig,aes(x=sex,fill=higher))+geom_bar()

Analyse du genre sur l’obtention du diplome Les hommes ont proportionellement mieux réussie à obtenir leur diplome que les femmes

ggplot(data=mprbig,aes(x=sex,fill=finalResult))+geom_bar()

Analyse du genre sur le niveau obtenu suite à l’examen Les femmes ont de meilleurs résultats que les hommes

ggplot(data=mprbig,aes(x=academicGrade,fill=sex))+geom_bar()

Analyse du niveau d’étude de la mère sur l’obtention de l’examen Les individus ayant réussie leur examen ont majoritairement une mère avec un haut niveau d’étude

ggplot(data=mprbig,aes(x=Medu,fill=finalResult))+geom_bar()

Analyse du support pédagogique suplémentaire sur l’aide éducatif familial Les individus ayant du support pédagogique suplémentaire ont plus d’aide éducatif familial

ggplot(data=mprbig,aes(x=schoolsup,fill=famsup))+geom_bar()

Analyse de l’envie de faire des études supérieurs sur le niveau d’étude de la mère Les individus ayant envie de faire des études supérieurs ont en grande partie une mère ayant un haut niveau d’étude

ggplot(data=mprbig,aes(x=Medu,fill=higher))+geom_bar()

Analyse de l’envie de faire des études supérieurs sur le niveau d’étude du père Les individus ayant envie de faire des études supérieurs ont majoritairement un père ayant un niveau d’étude élevé

ggplot(data=mprbig,aes(x=Fedu,fill=higher))+geom_bar()

Analyse du niveau d’étude du père sur l’obtention de l’examen Le niveau d’étude du père ne semble pas avoir d’impact sur l’obtention de l’examen

ggplot(data=mprbig,aes(x=Fedu,fill=finalResult))+geom_bar()

Analyse de la possession de internet sur l’obtention de l’examen La majorité des individus ayant réussie leur examen ont internet

ggplot(data=mprbig,aes(x=internet,fill=finalResult))+geom_bar()

Analyse de la possession de internet sur le niveau obtenu à l’examen Les meilleurs notes ont été obtenue par des individus ayant internet ( grade E )

ggplot(data=mprbig,aes(x=academicGrade,fill=internet))+geom_bar()

2.3 Étudiez les associations entre des paires de variables catégorielles

Analyse du genre sur l’envie de faire des études supérieurs

# association sex, envie de faire des études supérieurs
test = chisq.test(mprbig$sex,mprbig$higher)
test$statistic # la statistique du Chi2
X-squared 
 7.685935 
test$parameter # le nombre de degrés de libertés
df 
 1 
test$p.value # la p-value
[1] 0.005565284
test$observed # la matrice observée de départ
          mprbig$higher
mprbig$sex  no yes
         F   4 204
         M  16 171
test$expected # la matrice attendue sous l'hypothèse nulle d'absence de biais
          mprbig$higher
mprbig$sex        no      yes
         F 10.531646 197.4684
         M  9.468354 177.5316

On constate que la p-value étant inférieur à 5%, On rejette l’hypothèse de dépendance entre les deux variables

Analyse de l’envie de faire des études supérieurs sur l’obtention de l’examen

# association envie de faire des études supérieures, obtention de l'examen
test = chisq.test(mprbig$higher,mprbig$finalResult)
test$statistic # la statistique du Chi2
X-squared 
 8.353142 
test$parameter # le nombre de degrés de libertés
df 
 1 
test$p.value # la p-value
[1] 0.00385021
test$observed # la matrice observée de départ
             mprbig$finalResult
mprbig$higher fail pass
          no    13    7
          yes  117  258
test$expected # la matrice attendue sous l'hypothèse nulle d'absence de biais
             mprbig$finalResult
mprbig$higher       fail      pass
          no    6.582278  13.41772
          yes 123.417722 251.58228

On constate que la p-value étant inférieur à 5%, On rejette l’hypothèse de dépendance entre les deux variables

3 Etude des variables quantitatives

3.1 Étude individuelle des principales variables quantitatives

Etudier la varible age

student <- mprbig
var(student$age)
[1] 1.628285
age= ggplot(aes(x=age), data=student)+
  geom_histogram(binwidth = 0.50, fill='darkblue', color='darkblue')+
  ggtitle("Age of students")
age

L’histogramme ci-dessus montre clairement que la plupart des élèves ont entre 15 et 18 ans, ce qui est logique puisque la plupart des élèves commencent le lycée à l’âge de 15 ans et le terminent à 18 ans, étant donné qu’en général, les lycées du monde entier ne durent que 3 ans.

Etudier la varible studytime

ggplot(student,aes(x=studytime,y=G3)) + stat_summary(fun="mean", geom="bar",fill="darkblue") + ggtitle("G3 versus studytime")

Comme le montre la figure ci-dessus, les étudiants qui étudient plus longtemps obtiennent de meilleures notes finales que ceux qui étudient moins longtemps.

Étude de la variable failure

Répartition des échecs précédents.

ggplot(data = student, aes(x = failures)) +
  geom_histogram(binwidth = 0.50, fill='darkblue', color='darkblue') +
  geom_density() +
  ggtitle("Distribution of previous failures in student data") +
  xlab("Failures") +
  ylab("Distribution of Failures")+
  theme(plot.title=element_text(face="bold"))

Afficher la corrélation entre les échecs et les notes.

cor(student$G3, student$failures)
[1] -0.3604149
plot(x=student$failures, y=student$G3, xlab = "Failures", ylab = "Rank", col = "blue")

Étude de la variable absences

absences= ggplot(data=student,aes(x=absences, y=G1, col=sex))+geom_point()+geom_smooth(method="lm",se=F)+facet_grid(~sex)
absences

À partir du graphique ci-dessus, nous pouvons voir comment l’absence affecte négativement les performances des garçons, mais l’absence de cours n’a pas d’impact négatif sur les performances des filles en classe.

Étude de la variable G1

var(student$G1)
[1] 11.01705
ages= ggplot(data=student,aes(x=age, fill=sex))+geom_histogram(binwidth=0.50)
ages

Comme le montre clairement le graphique ci-dessus, la plupart des étudiants de plus de 18 ans sont des étudiants de sexe masculin car il n’y a pas d’étudiantes de plus de 20 ans.

G1 par rapport au sexe et à l’âge

G1=ggplot(data=student,aes(x=age, y=G1, col=sex, shape=sex))+geom_point()+geom_smooth(method="lm",se=F)+facet_grid(~sex)
G1

Nous pouvons voir que les performances des filles s’améliorent avec l’âge, cependant, une diminution des performances des garçons et nettement visible dans le graphique ci-dessus.

————– g2

3.2 Calcul de la matrice de corrélation pour les variables quantitatives.

Carte thermique pour la matrice de corrélation

numeric_features <- Filter(is.numeric, student)

library(pheatmap)
pheatmap(cor(numeric_features))

Comme montre la carte, la corrélation varie entre 1 et -1. La couleur rouge correspond à la corrélation élevée entre nos caractéristiques.

Par exemple : Corrélation positive : G1 et G3 Corrélation négative : les failures et le studytime présentent une corrélation négative

Matrice de nuage de points G1 et G3

#plot(with(student,G2), with(student,G3), xlab='G1', ylab='G3')
ggplot(student, aes(x=G2,y=G3)) + geom_point() + geom_smooth(method="lm", se=FALSE)

On peut remarquer le G3 présente une forte corrélation positive avec le G2.

Régression multiple entre la variable G3 par rapport à age

ggplot(student,aes(x=G3))+geom_histogram(fill="darkblue",color="darkblue",na.rm=TRUE)+
    labs(title="Classement des notes G3 par rapport à l'âge",y="",x="")+facet_wrap(~age)+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

4 Étude des relations entre les variables catégorielles et quantitatives.

4.1 Représenter les associations entre les variables quantitatives et les variables catégorielles (Boxplots, Bar charts for means, Stacked bar charts, Multiple histograms, etc.)

contengency <- table(student$G3,student$sex)
print(contengency)
    
      F  M
  0  23 15
  4   1  0
  5   3  4
  6  13  2
  7   4  5
  8  14 18
  9  17 11
  10 30 26
  11 29 18
  12 11 20
  13 17 14
  14 14 13
  15 16 17
  16  6 10
  17  3  3
  18  5  7
  19  2  3
  20  0  1

Consultation de la dépendance avec un stack bar chart.

ggplot(student,aes(x=G3,fill=sex))+geom_bar(position="stack")+theme(axis.text.x = element_text(angle = 45, hjust = 1))+
  labs(x="Note (G3)",y="Sex",title="Notes des élèves par sexe")

On fait ensuite une comparaison avec des % pour mieu representer le graph.

ggplot(student,aes(x=G3,fill=sex))+geom_bar(position="fill")+theme(axis.text.x = element_text(angle = 45, hjust = 1))+
  labs(x="Note (G3)",y="Sexe",title="Notes des élèves par sexe en %")

4.2 Effectuer des tests t pour comparer par paire la moyenne de certaines variables quantitatives en fonction des deux niveaux de certaines variables catégorielles binaires.

Créer un ensemble de données constitué uniquement de données mathématiques, avec des variables sexe (sex) et note finale(G3.

dataSexG3 = subset(student, select = c(sex, G3))
glimpse(dataSexG3)
Rows: 395
Columns: 2
$ sex <chr> "F", "F", "F", "F", "F", "M", "M", "F", "M", "M", "F", "F", "M", "M", "M", "F…
$ G3  <dbl> 6, 6, 10, 15, 10, 15, 11, 6, 19, 15, 9, 12, 14, 11, 16, 14, 14, 10, 5, 10, 15…

Nous avons donc une variable catégorielle qui est le sex. Et nous avons une variable quantitative qui est *G3$ (note final)

Histograms/barplot des différentes variables qui seront pertinentes pour les tests statistiques.

sexGraph <- table(dataSexG3$sex)

par(mfrow=c(2,2))
hist(dataSexG3$G3, breaks = 30, col = "darkblue", main = "Histogram de la variable student")
barplot(sexGraph, col="darkblue", main = "Barplot de la variable sex")

Graphiques de densité pour l’âge, les absences et le note finale

G3Dens <- density(dataSexG3$G3)
plot(G3Dens)

Nous pouvons voir quelques tendances claires dans les données.Il y a seulement un peu plus de femmes que d’hommes, et la note finale en mathématiques est à peu près également répartie.le plus grand nombre de personnes qui ont échoué aux tests, c’est-à-dire qui ont reçu la note 0, fera pencher toute analyse des moyennes des notes finales nettement vers la gauche. Cela est assez évident si l’on regarde le graphique de densité ci-dessus.

4.2 Effectuer des tests pour comparer par paire la moyenne de certaines variables quantitatives en fonction des deux niveaux de certaines variables catégorielles binaires.

Le test de Bartlett

bartlett.test(G3[dataSexG3$G3 > 0] ~ sex[dataSexG3$G3 > 0], data=dataSexG3)

    Bartlett test of homogeneity of variances

data:  G3[dataSexG3$G3 > 0] by sex[dataSexG3$G3 > 0]
Bartlett's K-squared = 0.12148, df = 1, p-value = 0.7274

Le test de Levene

leveneTest(y = dataSexG3$G3, group = dataSexG3$sex)
dataSexG3$sex coerced to factor.
Levene's Test for Homogeneity of Variance (center = median)
       Df F value Pr(>F)
group   1  0.0685 0.7937
      393               

Visualisation par Boxplot des notes finales pour chaque sexe.

ggplot(dataSexG3, aes(x = sex, y = G3)) +
        geom_boxplot(col = "black") +
        ggtitle("Moyennes des notes finales par sexe")

En se basant sur les deux tests et la visualisation des données en question, on peut affirmer sans risque que l’hypothèse d’homogénéité de la variance est remplie dans cet exemple.

L’homogénéité des variances t.test

t.test(dataSexG3$G3[dataSexG3$sex=="F" & dataSexG3$G3>0], dataSexG3$G3[dataSexG3$sex=="M" & dataSexG3$G3>0])

    Welch Two Sample t-test

data:  dataSexG3$G3[dataSexG3$sex == "F" & dataSexG3$G3 > 0] and dataSexG3$G3[dataSexG3$sex == "M" & dataSexG3$G3 > 0]
t = -1.9386, df = 351.54, p-value = 0.05335
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -1.331331307  0.009583978
sample estimates:
mean of x mean of y 
 11.20541  11.86628 

Les notes finales moyennes des filles et des garçons sont présentées dans la console après avoir effectué le test t. Les filles ont obtenu une note de 11,20, et les garçons une note moyenne de 11,86. Cette différence est égale à environ 0,66.

4.3 ANOVA pour trouver la différence entre l’âge et les notes

age.g3 <- aov(G3 ~ factor(age), data = student)
TukeyHSD(age.g3)
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = G3 ~ factor(age), data = student)

$`factor(age)`
            diff        lwr        upr     p adj
16-15 -0.2272514  -2.265444  1.8109414 0.9999747
17-15 -0.9805874  -3.046104  1.0849292 0.8346939
18-15 -1.7073171  -3.862680  0.4480461 0.2374238
19-15 -3.0477642  -6.250733  0.1552050 0.0753852
20-15  2.7439024  -5.368590 10.8563947 0.9695415
21-15 -4.2560976 -18.141054  9.6288584 0.9825598
22-15 -3.2560976 -17.141054 10.6288584 0.9965457
17-16 -0.7533359  -2.696271  1.1895995 0.9368291
18-16 -1.4800657  -3.518258  0.5581271 0.3461517
19-16 -2.8205128  -5.945837  0.3048114 0.1110364
20-16  2.9711538  -5.110997 11.0533052 0.9521487
21-16 -4.0288462 -17.896097  9.8384045 0.9872488
22-16 -3.0288462 -16.896097 10.8384045 0.9977951
18-17 -0.7267297  -2.792246  1.3387868 0.9621847
19-17 -2.0671769  -5.210389  1.0760349 0.4802791
20-17  3.7244898  -4.364595 11.8135750 0.8555397
21-17 -3.2755102 -17.146803 10.5957828 0.9963925
22-17 -2.2755102 -16.146803 11.5957828 0.9996581
19-18 -1.3404472  -4.543416  1.8625221 0.9074950
20-18  4.4512195  -3.661273 12.5637118 0.7052971
21-18 -2.5487805 -16.433736 11.3361755 0.9992827
22-18 -1.5487805 -15.433736 12.3361755 0.9999746
20-19  5.7916667  -2.659721 14.2430543 0.4242194
21-19 -1.2083333 -15.293979 12.8773127 0.9999958
22-19 -0.2083333 -14.293979 13.8773127 1.0000000
21-20 -7.0000000 -22.936089  8.9360893 0.8835131
22-20 -6.0000000 -21.936089  9.9360893 0.9457419
22-21  1.0000000 -18.517644 20.5176436 0.9999999

Les résultats montrent qu’il n’y a pas de différence dans les notes finales entre les différents groupes d’âge. Les valeurs p Adj sont toutes supérieures à 0,05.

5 Clustering

5.1 K-moyennes

Preparion de la donné

# nombre de ligne
nbl <- 40
# creation du data frame
kdf <- data.frame(mprbig$age,mprbig$studytime,mprbig$failures,mprbig$absences,mprbig$G1,mprbig$G2,mprbig$G3)
#scaling the data
kdf <- scale(kdf[0:nbl,])

Désignation du meilleur nombre de clusters

#Average Silhouette Method
fviz_nbclust(kdf, kmeans, method = "silhouette")

#Gap Statistic Method (methode pour savoir le nombre de cluster)
gap_stat <- clusGap(kdf, FUN = kmeans, nstart = 25, K.max = 10)
Clustering k = 1,2,..., K.max (= 10): .. done
Bootstrapping, b = 1,2,..., B (= 100)  [one "." per sample]:
.................................................. 50 
.................................................. 100 
fviz_gap_stat(gap_stat)

Visualisation des clusters

krbig <- kmeans(kdf, centers = 2, nstart = 50)
fviz_cluster(krbig, data = kdf)

Anlalise des clusters

fkrbig <- cbind(mprbig[0:nbl,], clusterNum = krbig$cluster)
ggplot(fkrbig, aes(x = clusterNum, y = G3)) + 
  geom_boxplot(aes(group = clusterNum)) + 
  stat_summary(fun = "mean", geom = "point", size= 2) +
  ggtitle("Note par rapport au cluster")

Dans le le graphique ci-dessus, nous pouvons observer que le premier cluster montre ceux qui ont reussi et dans le deuxiéme cluster ceux qui n’ont pas réussi.

On remarque que les cluster se font par rapport au note , on peux en déduire que les variables utilisées n’ont pas d’influence sur les notes

5.2 Regroupement hiérarchique

Visualisation du Regroupement hiérarchique

#nombre de ligne
nbl <- 40
#creation du data frame
hdf <- data.frame(mprbig$age,mprbig$studytime,mprbig$failures,mprbig$absences,mprbig$G1,mprbig$G2,mprbig$G3)
# la matrice de distance
distmat <- dist(hdf[0:nbl,],method = 'euclidean')
hrbig <- hclust(distmat)
plot(hrbig)

On remarque bien qu’il y a deux grande partie

Découpe de l’arbre en clusters

#decoupe de l'arbre en cluster
cut <- cutree(hrbig,2)
plot(hrbig)
rect.hclust(hrbig , k = 2, border = 2:6)

Analise des donner dans chaque clusters

fhrbig <- cbind(mprbig[0:nbl,], clusterNum = cut)
ggplot(fhrbig, aes(x = clusterNum, y = G3)) + 
  geom_boxplot(aes(group = clusterNum)) + 
  stat_summary(fun = "mean", geom = "point", size= 2) +
  ggtitle("Note par rapport au cluster")

On remarque que c’est la meme disposition qu’avec le k-moyenne mais les cluster sont inversés : dans le premier nous avons les moins bonne notes et dans le 2ieme les meilleurs notes

On remarque les mêmes clusters que le k-moyenne, on peux dire que les variable utilisé n’ont pas d’influence sur les notes

6 Conlusion

Suite à l’étude que nous avons mené sur les données du fichier CSV/XLXS, nous pouvons conclure que le facteur qui influe le plus sur la notation des étudiants est le genre. En effet, nous avons constaté que les filles sont beaucoup plus motivée à l’idée de poursuivre des études supérieures et ont plus de support pédagogique que les garçons(support de cours personnel supplémentaire).

Pour les garçons, ils sont plus âgés, étudient moins et ont plus d’absences que les filles. Cela entraîne un retard qu’ils n’arrivent pas à rattraper par la suite.

Ce qui permet donc d’affirmer que les filles s’en mieux que les garçons dans leurs études de manière générale.

LS0tCnRpdGxlOiAiw4l0dWRpZXIgbGEgcGVyZm9ybWFuY2UgZGVzIMOpdHVkaWFudHMiCm91dHB1dDoKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAotLS0KKipNZW1icmUgZHUgR3JvdXBlIDoqKiBJc21hZWwgTW9oYW1lZCAyOTU0NjUsIFJvbWFpbiBQaW9uIDIyMjUyNSwgTWF0aGlldSBHdWlsYmF1ZCAyMjMwOTYgLyAKKipSZXBvIEdpdGh1YiA6ICoqIGh0dHBzOi8vZ2l0aHViLmNvbS9Nb2hhbWVkWGkvNXJiaWdfcHJvamVjdC5naXQKCiMgSW50cm9kdWN0aW9uCkNlcyBkb25uw6llcyBjb25jZXJuZW50IGxlcyDDqWzDqHZlcyBkZSBkZXV4IMOpY29sZXMgcHVibGlxdWVzIHBvcnR1Z2Fpc2VzIGV0IG9udCDDqXTDqSByZWN1ZWlsbGllcyBhdSBjb3VycyBkZSBsJ2FubsOpZSBzY29sYWlyZSAyMDA1LTIwMDYuIE5vdXMgw6l0dWRpZXJvbnMgdG91dGVzIGxlcyB2YXJpYWJsZXMgZXQgbGV1cnMgaW50ZXJhY3Rpb25zLCBlbiBtZXR0YW50IGwnYWNjZW50IHN1ciBsZXMgZmFjdGV1cnMgcXVpIGluZmx1ZW50IHN1ciBsYSByw6l1c3NpdGUgZGVzIMOpbMOodmVzLgoKIyAxIFByw6lhcGFydGlvbiBkZSBsYSBkYXRhCiMjIDEuMSBWw6lyaWZpY2F0aW9uIGRlcyB2YXJpYWJsZXMKQ2hhcmdlbWVudCBkZXMgbGlicmFpcmllcwpgYGB7cn0KaWYoIXJlcXVpcmUoImdncGxvdDIiKSl7aW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpfQppZighcmVxdWlyZSgiZHBseXIiKSl7aW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKX0KaWYoIXJlcXVpcmUoImdnd29yZGNsb3VkIikpe2luc3RhbGwucGFja2FnZXMoImdnd29yZGNsb3VkIil9CmlmKCFyZXF1aXJlKCJyZWFkeGwiKSl7aW5zdGFsbC5wYWNrYWdlcygicmVhZHhsIil9CmlmKCFyZXF1aXJlKCJmYWN0b3JwbG90Iikpe2luc3RhbGwucGFja2FnZXMoImZhY3RvcnBsb3QiKX0KaWYoIXJlcXVpcmUoIndvcmRjbG91ZDIiKSl7aW5zdGFsbC5wYWNrYWdlcygid29yZGNsb3VkMiIpfQppZighcmVxdWlyZSgicmVhZHhsIikpe2luc3RhbGwucGFja2FnZXMoInJlYWR4bCIpfQppZighcmVxdWlyZSgiZmFjdG9ycGxvdCIpKXtpbnN0YWxsLnBhY2thZ2VzKCJmYWN0b3JwbG90Iil9CmlmKCFyZXF1aXJlKCJwaGVhdG1hcCIpKXtpbnN0YWxsLnBhY2thZ2VzKCJwaGVhdG1hcCIpfQppZighcmVxdWlyZSgiY2FyIikpe2luc3RhbGwucGFja2FnZXMoImNhciIpfQppZighcmVxdWlyZSgiZmFjdG9leHRyYSIpKXtpbnN0YWxsLnBhY2thZ2VzKCJmYWN0b2V4dHJhIil9CmlmKCFyZXF1aXJlKCJjbHVzdGVyIikpe2luc3RhbGwucGFja2FnZXMoImNsdXN0ZXIiKX0KaWYoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKXtpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoY2x1c3RlcikKbGlicmFyeShmYWN0b2V4dHJhKQpsaWJyYXJ5KGdncGxvdDIpCm9wdGlvbnMod2Fybj0tMSkKbGlicmFyeShkcGx5cikKbGlicmFyeShyZWFkcikKbGlicmFyeShwc3ljaCkKbGlicmFyeShnZ3dvcmRjbG91ZCkKbGlicmFyeSh3b3JkY2xvdWQyKQpsaWJyYXJ5KHJlYWR4bCkKbGlicmFyeShmYWN0b3JwbG90KQpsaWJyYXJ5KHBoZWF0bWFwKQpsaWJyYXJ5KGNhcikKYGBgCgpDaGFyZ2VtZW50IGRlcyBkb25uw6llcy4KYGBge3J9Cm1wcmJpZyA8LSByZWFkX2V4Y2VsKCJNUC01UkJJRy54bHN4IikKYGBgCgpBZmZpY2hhZ2UgZGVzIGRpZmbDqXJlbnRlcyB2YXJpYWJsZTsKYGBge3J9CmhlYWQobXByYmlnKQpgYGAKYGBge3J9CnN1bW1hcnkobXByYmlnKQpgYGAKClbDqXJpZmljYXRpb24gcydpbCBuJ3kgYSBwYXMgZGUgdmFsYXVyZSBtYW5xdWFudGUKYGBge3J9CnN1bShpcy5uYShtcHJiaWcpKQpgYGAKCiMjIDEuMiBBam91dCBkZSBsYSB2YXJpYWJsZSBmaW5hbFJlc3VsdApgYGB7cn0KZmluYWxSZXN1bHQgPC0gTlVMTApmb3IgKHggaW4gbXByYmlnJEczKSB7CiAgaWYgKHggPCAxMCApIHsKICAgZmluYWxSZXN1bHQgPC0gYyhmaW5hbFJlc3VsdCwiZmFpbCIpCiAgfSBlbHNlIHsKICAgZmluYWxSZXN1bHQgPC0gYyhmaW5hbFJlc3VsdCwicGFzcyIpCiAgfQp9Cm1wcmJpZyA8LSBkYXRhLmZyYW1lKG1wcmJpZyxmaW5hbFJlc3VsdCkKbXByYmlnCmBgYAoKIyMgMS4zIEFqb3V0IGRlIGxhIHZhcmlhYmxlIGFjYWRlbWljR3JhZGUKYGBge3J9CmFjYWRlbWljR3JhZGUgPC0gTlVMTApmb3IgKHggaW4gbXByYmlnJEczKSB7CiAgaWYgKHggPj0gMTYgICkgewogICBhY2FkZW1pY0dyYWRlIDwtIGMoYWNhZGVtaWNHcmFkZSwiQSIpCiAgfQogIGlmICh4ID49IDE0ICYmIHggPCAxNikgewogICBhY2FkZW1pY0dyYWRlIDwtIGMoYWNhZGVtaWNHcmFkZSwiQiIpCiAgfQogIGlmICh4ID49IDEyICYmIHggPCAxNCkgewogICBhY2FkZW1pY0dyYWRlIDwtIGMoYWNhZGVtaWNHcmFkZSwiQyIpCiAgfQogIGlmICh4ID49IDEwICYmIHggPCAxMikgewogICBhY2FkZW1pY0dyYWRlIDwtIGMoYWNhZGVtaWNHcmFkZSwiRCIpCiAgfQogIGlmICh4IDw9IDkpewogICAgYWNhZGVtaWNHcmFkZSA8LSBjKGFjYWRlbWljR3JhZGUsIkUiKQogIH0KfQptcHJiaWcgPC0gZGF0YS5mcmFtZShtcHJiaWcsYWNhZGVtaWNHcmFkZSkKbXByYmlnCmBgYAoKIyAyIEV0dWRlIGRlcyB2YXJpYWJsZXMgY2F0w6lnb3JpZWxsZXMKCiMjIDIuMSDDiXR1ZGlleiBpbmRpdmlkdWVsbGVtZW50IGxlcyBwcmluY2lwYWxlcyB2YXJpYWJsZXMgY2F0w6lnb3JpZWxsZXMKCkxlIGdlbnJlCkxhIG1ham9yaXTDqSBkZXMgaW5kaXZpZHVzIHNvbnQgZGVzIGZlbW1lcwpgYGB7cn0KZ2dwbG90KGRhdGE9bXByYmlnLGFlcyh4PXNleCxmaWxsPXNleCkpICsgZ2VvbV9iYXIoKQpgYGAKTCfDqWR1Y2F0aW9uIGRlIGxhIG3DqHJlCkxhIG1ham9yaXTDqSBkZXMgaW5kaXZpZHVzIG9udCB1bmUgbcOocmUgYXZlYyB1biBuaXZlYXUgZCfDqXR1ZGUgw6lsZXbDqQpgYGB7cn0KZ2dwbG90KGRhdGE9bXByYmlnLGFlcyh4PU1lZHUsZmlsbD1NZWR1KSkrZ2VvbV9iYXIoKQpgYGAKTCfDqWR1Y2F0aW9uIGR1IHDDqHJlCkxhIG1ham9yaXTDqSBkZXMgaW5kaXZpZHVzIG9udCB1biBww6hyZSBheWFudCB1biBuaXZlYXUgZCfDqXR1ZGUgw6lsZXbDqQpgYGB7cn0KZ2dwbG90KGRhdGE9bXByYmlnLGFlcyh4PUZlZHUsZmlsbD1GZWR1KSkrZ2VvbV9iYXIoKQpgYGAKTGUgc3VwcG9ydCBww6lkYWdvZ2lxdWUgc3VwbMOpbWVudGFpcmUKTGEgbWFqb3JpdMOpIGRlcyBpbmRpdmlkdXMgbidvbnQgcGFzIGRlIHN1cHBvcnQgcMOpZGFnb2dpcXVlIHN1cGzDqW1lbnRhaXJlCmBgYHtyfQpnZ3Bsb3QoZGF0YT1tcHJiaWcsYWVzKHg9c2Nob29sc3VwLGZpbGw9c2Nob29sc3VwKSkrZ2VvbV9iYXIoKQpgYGAKTGUgc291dGllbiDDqWR1Y2F0aWYgZmFtaWxpYWwKTGEgbWFqb3JpdMOpIGRlcyBpbmRpdmlkdXMgb250IHVuIHNvdXRpZW4gw6lkdWNhdGlmIGZhbWlsaWFsCmBgYHtyfQpnZ3Bsb3QoZGF0YT1tcHJiaWcsYWVzKHg9ZmFtc3VwLGZpbGw9ZmFtc3VwKSkrZ2VvbV9iYXIoKQpgYGAKTGVzIGNvdXJzIGRlIG1hdGjDqW1hdGlxdWVzIHBheWFudCBzdXBsw6ltZW50YWlyZQpMYSBtYWpvcml0w6kgZGVzIGluZGl2aWR1cyBuZSBzdWl2ZW50IHBhcyBkZSBjb3VycyBkZSBtYXRow6ltYXRpcXVlcyBwYXlhbnQgc3VwbMOpbWVudGFpcmUKYGBge3J9CmdncGxvdChkYXRhPW1wcmJpZyxhZXMoeD1wYWlkLGZpbGw9cGFpZCkpK2dlb21fYmFyKCkKYGBgCk5vbWJyZSBkJ2luZGl2aWR1cyB2b3VsYW50IHN1aXZyZSBkZXMgw6l0dWRlcyBzdXDDqXJpZXVycwpMYSBtYWpvcml0w6kgZGVzIGluZGl2aWR1cyB2ZXVsZW50IHN1aXZyZSBkZXMgw6l0dWRlcyBzdXDDqXJpZXVycwpgYGB7cn0KZ2dwbG90KGRhdGE9bXByYmlnLGFlcyh4PWhpZ2hlcixmaWxsPWhpZ2hlcikpK2dlb21fYmFyKCkKYGBgCkwnYWNjw6hzIMOgIGludGVybmV0IMOgIHNvbiBkb21pY2lsZQpMYSBtYWpvcml0w6kgZGVzIGluZGl2aWR1cyBvbnQgYWNjw6hzIMOgIGludGVybmV0CmBgYHtyfQpnZ3Bsb3QoZGF0YT1tcHJiaWcsYWVzKHg9aW50ZXJuZXQsZmlsbD1pbnRlcm5ldCkpK2dlb21fYmFyKCkKYGBgCkxlcyBhZG1pcwpMYSBtYWpvcml0w6kgZGVzIGluZGl2aWR1cyBvbnQgcsOpdXNzaWUgbGV1ciBleGFtZW4KYGBge3J9CmdncGxvdChkYXRhPW1wcmJpZyxhZXMoeD1maW5hbFJlc3VsdCxmaWxsPWZpbmFsUmVzdWx0KSkrZ2VvbV9iYXIoKQpgYGAKTGUgbml2ZWF1IG9idGVudSDDoCBsJ2V4YW1lbgpMYSBtYWpvcml0w6kgZGVzIGluZGl2aWR1cyBvbnQgb2J0ZW51IGxlIG5pdmVhdSBFCmBgYHtyfQpnZ3Bsb3QoZGF0YT1tcHJiaWcsYWVzKHg9YWNhZGVtaWNHcmFkZSxmaWxsPWFjYWRlbWljR3JhZGUpKStnZW9tX2JhcigpCmBgYAojIyAyLjIgUmVwcsOpc2VudGUgbGVzIGFzc29jaWF0aW9ucyBlbnRyZSBkZXMgcGFpcmVzIGRlIHZhcmlhYmxlcyBjYXTDqWdvcmllbGxlcwoKQW5hbHlzZSBkdSBnZW5yZSBzdXIgbGUgc3VwcG9ydCBww6lkYWdvZ2lxdWUgc3VwbMOpbWVudGFpcmUKUHJvcG9ydGlvbmVsbGVtZW50LCBsZXMgZmVtbWVzIHJlw6dvaXZlbnQgcGx1cyBzb3V2ZW50IHVuIHN1cHBvcnQgcMOpZGFnb2dpcXVlIHN1cGzDqW1lbnRhaXJlIHF1ZSBsZXMgaG9tbWVzCmBgYHtyfQpnZ3Bsb3QoZGF0YT1tcHJiaWcsYWVzKHg9c2V4LGZpbGw9c2Nob29sc3VwKSkrZ2VvbV9iYXIoKQpgYGAKQW5hbHlzZSBkdSBnZW5yZSBzdXIgbCdhaWRlIMOpZHVjYXRpZiBmYW1pbGlhbApMZXMgaG9tbWVzIHJlw6dvaXZlbnQgcGx1cyBzb3V2ZW50IGRlIGwnYWlkZSDDqWR1Y2F0aWYgZmFtaWxpYWwgcXVlIGxlcyBmZW1tZXMKYGBge3J9CmdncGxvdChkYXRhPW1wcmJpZyxhZXMoeD1zZXgsZmlsbD1mYW1zdXApKStnZW9tX2JhcigpCmBgYApBbmFseXNlIGR1IGdlbnJlIHN1ciBsJ2VudmllIGRlIHN1aXZyZSBkZXMgw6l0dWRlcyBzdXDDqXJpZXVycwpMZXMgZmVtbWVzIG9udCBtYWpvcml0YWlyZW1lbnQgZW52aWUgZGUgZmFpcmUgZGVzIMOpdHVkZXMgc3Vww6lyaWV1cnMKYGBge3J9CmdncGxvdChkYXRhPW1wcmJpZyxhZXMoeD1zZXgsZmlsbD1oaWdoZXIpKStnZW9tX2JhcigpCmBgYApBbmFseXNlIGR1IGdlbnJlIHN1ciBsJ29idGVudGlvbiBkdSBkaXBsb21lCkxlcyBob21tZXMgb250IHByb3BvcnRpb25lbGxlbWVudCBtaWV1eCByw6l1c3NpZSDDoCBvYnRlbmlyIGxldXIgZGlwbG9tZSBxdWUgbGVzIGZlbW1lcwpgYGB7cn0KZ2dwbG90KGRhdGE9bXByYmlnLGFlcyh4PXNleCxmaWxsPWZpbmFsUmVzdWx0KSkrZ2VvbV9iYXIoKQpgYGAKQW5hbHlzZSBkdSBnZW5yZSBzdXIgbGUgbml2ZWF1IG9idGVudSBzdWl0ZSDDoCBsJ2V4YW1lbgpMZXMgZmVtbWVzIG9udCBkZSBtZWlsbGV1cnMgcsOpc3VsdGF0cyBxdWUgbGVzIGhvbW1lcwpgYGB7cn0KZ2dwbG90KGRhdGE9bXByYmlnLGFlcyh4PWFjYWRlbWljR3JhZGUsZmlsbD1zZXgpKStnZW9tX2JhcigpCmBgYApBbmFseXNlIGR1IG5pdmVhdSBkJ8OpdHVkZSBkZSBsYSBtw6hyZSBzdXIgbCdvYnRlbnRpb24gZGUgbCdleGFtZW4KTGVzIGluZGl2aWR1cyBheWFudCByw6l1c3NpZSBsZXVyIGV4YW1lbiBvbnQgbWFqb3JpdGFpcmVtZW50IHVuZSBtw6hyZSBhdmVjIHVuIGhhdXQgbml2ZWF1IGQnw6l0dWRlCmBgYHtyfQpnZ3Bsb3QoZGF0YT1tcHJiaWcsYWVzKHg9TWVkdSxmaWxsPWZpbmFsUmVzdWx0KSkrZ2VvbV9iYXIoKQpgYGAKQW5hbHlzZSBkdSBzdXBwb3J0IHDDqWRhZ29naXF1ZSBzdXBsw6ltZW50YWlyZSBzdXIgbCdhaWRlIMOpZHVjYXRpZiBmYW1pbGlhbApMZXMgaW5kaXZpZHVzIGF5YW50IGR1IHN1cHBvcnQgcMOpZGFnb2dpcXVlIHN1cGzDqW1lbnRhaXJlIG9udCBwbHVzIGQnYWlkZSDDqWR1Y2F0aWYgZmFtaWxpYWwKYGBge3J9CmdncGxvdChkYXRhPW1wcmJpZyxhZXMoeD1zY2hvb2xzdXAsZmlsbD1mYW1zdXApKStnZW9tX2JhcigpCmBgYApBbmFseXNlIGRlIGwnZW52aWUgZGUgZmFpcmUgZGVzIMOpdHVkZXMgc3Vww6lyaWV1cnMgc3VyIGxlIG5pdmVhdSBkJ8OpdHVkZSBkZSBsYSBtw6hyZQpMZXMgaW5kaXZpZHVzIGF5YW50IGVudmllIGRlIGZhaXJlIGRlcyDDqXR1ZGVzIHN1cMOpcmlldXJzIG9udCBlbiBncmFuZGUgcGFydGllIHVuZSBtw6hyZSBheWFudCB1biBoYXV0IG5pdmVhdSBkJ8OpdHVkZQpgYGB7cn0KZ2dwbG90KGRhdGE9bXByYmlnLGFlcyh4PU1lZHUsZmlsbD1oaWdoZXIpKStnZW9tX2JhcigpCmBgYApBbmFseXNlIGRlIGwnZW52aWUgZGUgZmFpcmUgZGVzIMOpdHVkZXMgc3Vww6lyaWV1cnMgc3VyIGxlIG5pdmVhdSBkJ8OpdHVkZSBkdSBww6hyZQpMZXMgaW5kaXZpZHVzIGF5YW50IGVudmllIGRlIGZhaXJlIGRlcyDDqXR1ZGVzIHN1cMOpcmlldXJzIG9udCBtYWpvcml0YWlyZW1lbnQgdW4gcMOocmUgYXlhbnQgdW4gbml2ZWF1IGQnw6l0dWRlIMOpbGV2w6kKYGBge3J9CmdncGxvdChkYXRhPW1wcmJpZyxhZXMoeD1GZWR1LGZpbGw9aGlnaGVyKSkrZ2VvbV9iYXIoKQpgYGAKQW5hbHlzZSBkdSBuaXZlYXUgZCfDqXR1ZGUgZHUgcMOocmUgc3VyIGwnb2J0ZW50aW9uIGRlIGwnZXhhbWVuCkxlIG5pdmVhdSBkJ8OpdHVkZSBkdSBww6hyZSBuZSBzZW1ibGUgcGFzIGF2b2lyIGQnaW1wYWN0IHN1ciBsJ29idGVudGlvbiBkZSBsJ2V4YW1lbgpgYGB7cn0KZ2dwbG90KGRhdGE9bXByYmlnLGFlcyh4PUZlZHUsZmlsbD1maW5hbFJlc3VsdCkpK2dlb21fYmFyKCkKYGBgCkFuYWx5c2UgZGUgbGEgcG9zc2Vzc2lvbiBkZSBpbnRlcm5ldCBzdXIgbCdvYnRlbnRpb24gZGUgbCdleGFtZW4KTGEgbWFqb3JpdMOpIGRlcyBpbmRpdmlkdXMgYXlhbnQgcsOpdXNzaWUgbGV1ciBleGFtZW4gb250IGludGVybmV0CmBgYHtyfQpnZ3Bsb3QoZGF0YT1tcHJiaWcsYWVzKHg9aW50ZXJuZXQsZmlsbD1maW5hbFJlc3VsdCkpK2dlb21fYmFyKCkKYGBgCkFuYWx5c2UgZGUgbGEgcG9zc2Vzc2lvbiBkZSBpbnRlcm5ldCBzdXIgbGUgbml2ZWF1IG9idGVudSDDoCBsJ2V4YW1lbgpMZXMgbWVpbGxldXJzIG5vdGVzIG9udCDDqXTDqSBvYnRlbnVlIHBhciBkZXMgaW5kaXZpZHVzIGF5YW50IGludGVybmV0ICggZ3JhZGUgRSApCmBgYHtyfQpnZ3Bsb3QoZGF0YT1tcHJiaWcsYWVzKHg9YWNhZGVtaWNHcmFkZSxmaWxsPWludGVybmV0KSkrZ2VvbV9iYXIoKQpgYGAKIyMgMi4zIMOJdHVkaWV6IGxlcyBhc3NvY2lhdGlvbnMgZW50cmUgZGVzIHBhaXJlcyBkZSB2YXJpYWJsZXMgY2F0w6lnb3JpZWxsZXMKCkFuYWx5c2UgZHUgZ2VucmUgc3VyIGwnZW52aWUgZGUgZmFpcmUgZGVzIMOpdHVkZXMgc3Vww6lyaWV1cnMKYGBge3J9CiMgYXNzb2NpYXRpb24gc2V4LCBlbnZpZSBkZSBmYWlyZSBkZXMgw6l0dWRlcyBzdXDDqXJpZXVycwp0ZXN0ID0gY2hpc3EudGVzdChtcHJiaWckc2V4LG1wcmJpZyRoaWdoZXIpCnRlc3Qkc3RhdGlzdGljICMgbGEgc3RhdGlzdGlxdWUgZHUgQ2hpMgp0ZXN0JHBhcmFtZXRlciAjIGxlIG5vbWJyZSBkZSBkZWdyw6lzIGRlIGxpYmVydMOpcwp0ZXN0JHAudmFsdWUgIyBsYSBwLXZhbHVlCnRlc3Qkb2JzZXJ2ZWQgIyBsYSBtYXRyaWNlIG9ic2VydsOpZSBkZSBkw6lwYXJ0CnRlc3QkZXhwZWN0ZWQgIyBsYSBtYXRyaWNlIGF0dGVuZHVlIHNvdXMgbCdoeXBvdGjDqHNlIG51bGxlIGQnYWJzZW5jZSBkZSBiaWFpcwoKYGBgCk9uIGNvbnN0YXRlIHF1ZSBsYSBwLXZhbHVlIMOpdGFudCBpbmbDqXJpZXVyIMOgIDUlLCBPbiByZWpldHRlIGwnaHlwb3Row6hzZSBkZSBkw6lwZW5kYW5jZSBlbnRyZSBsZXMgZGV1eCB2YXJpYWJsZXMKCkFuYWx5c2UgZGUgbCdlbnZpZSBkZSBmYWlyZSBkZXMgw6l0dWRlcyBzdXDDqXJpZXVycyBzdXIgbCdvYnRlbnRpb24gZGUgbCdleGFtZW4KYGBge3J9CiMgYXNzb2NpYXRpb24gZW52aWUgZGUgZmFpcmUgZGVzIMOpdHVkZXMgc3Vww6lyaWV1cmVzLCBvYnRlbnRpb24gZGUgbCdleGFtZW4KdGVzdCA9IGNoaXNxLnRlc3QobXByYmlnJGhpZ2hlcixtcHJiaWckZmluYWxSZXN1bHQpCnRlc3Qkc3RhdGlzdGljICMgbGEgc3RhdGlzdGlxdWUgZHUgQ2hpMgp0ZXN0JHBhcmFtZXRlciAjIGxlIG5vbWJyZSBkZSBkZWdyw6lzIGRlIGxpYmVydMOpcwp0ZXN0JHAudmFsdWUgIyBsYSBwLXZhbHVlCnRlc3Qkb2JzZXJ2ZWQgIyBsYSBtYXRyaWNlIG9ic2VydsOpZSBkZSBkw6lwYXJ0CnRlc3QkZXhwZWN0ZWQgIyBsYSBtYXRyaWNlIGF0dGVuZHVlIHNvdXMgbCdoeXBvdGjDqHNlIG51bGxlIGQnYWJzZW5jZSBkZSBiaWFpcwpgYGAKT24gY29uc3RhdGUgcXVlIGxhIHAtdmFsdWUgw6l0YW50IGluZsOpcmlldXIgw6AgNSUsIE9uIHJlamV0dGUgbCdoeXBvdGjDqHNlIGRlIGTDqXBlbmRhbmNlIGVudHJlIGxlcyBkZXV4IHZhcmlhYmxlcwoKIyAzIEV0dWRlIGRlcyB2YXJpYWJsZXMgcXVhbnRpdGF0aXZlcwojIyAzLjEgw4l0dWRlIGluZGl2aWR1ZWxsZSBkZXMgcHJpbmNpcGFsZXMgdmFyaWFibGVzIHF1YW50aXRhdGl2ZXMKIyMjIEV0dWRpZXIgbGEgdmFyaWJsZSAqKiphZ2UqKioKYGBge3J9CnN0dWRlbnQgPC0gbXByYmlnCnZhcihzdHVkZW50JGFnZSkKYWdlPSBnZ3Bsb3QoYWVzKHg9YWdlKSwgZGF0YT1zdHVkZW50KSsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNTAsIGZpbGw9J2RhcmtibHVlJywgY29sb3I9J2RhcmtibHVlJykrCiAgZ2d0aXRsZSgiQWdlIG9mIHN0dWRlbnRzIikKYWdlCmBgYAoKTCdoaXN0b2dyYW1tZSBjaS1kZXNzdXMgbW9udHJlIGNsYWlyZW1lbnQgcXVlIGxhIHBsdXBhcnQgZGVzIMOpbMOodmVzIG9udCBlbnRyZSAxNSBldCAxOCBhbnMsIGNlIHF1aSBlc3QgbG9naXF1ZSBwdWlzcXVlIGxhIHBsdXBhcnQgZGVzIMOpbMOodmVzIGNvbW1lbmNlbnQgbGUgbHljw6llIMOgIGwnw6JnZSBkZSAxNSBhbnMgZXQgbGUgdGVybWluZW50IMOgIDE4IGFucywgw6l0YW50IGRvbm7DqSBxdSdlbiBnw6luw6lyYWwsIGxlcyBseWPDqWVzIGR1IG1vbmRlIGVudGllciBuZSBkdXJlbnQgcXVlIDMgYW5zLgoKIyMjIEV0dWRpZXIgbGEgdmFyaWJsZSAqKipzdHVkeXRpbWUqKioKYGBge3J9CmdncGxvdChzdHVkZW50LGFlcyh4PXN0dWR5dGltZSx5PUczKSkgKyBzdGF0X3N1bW1hcnkoZnVuPSJtZWFuIiwgZ2VvbT0iYmFyIixmaWxsPSJkYXJrYmx1ZSIpICsgZ2d0aXRsZSgiRzMgdmVyc3VzIHN0dWR5dGltZSIpCmBgYApDb21tZSBsZSBtb250cmUgbGEgZmlndXJlIGNpLWRlc3N1cywgbGVzIMOpdHVkaWFudHMgcXVpIMOpdHVkaWVudCBwbHVzIGxvbmd0ZW1wcyBvYnRpZW5uZW50IGRlIG1laWxsZXVyZXMgbm90ZXMgZmluYWxlcyBxdWUgY2V1eCBxdWkgw6l0dWRpZW50IG1vaW5zIGxvbmd0ZW1wcy4KCiMjIyDDiXR1ZGUgZGUgbGEgdmFyaWFibGUgZmFpbHVyZQpSw6lwYXJ0aXRpb24gZGVzIMOpY2hlY3MgcHLDqWPDqWRlbnRzLgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBzdHVkZW50LCBhZXMoeCA9IGZhaWx1cmVzKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41MCwgZmlsbD0nZGFya2JsdWUnLCBjb2xvcj0nZGFya2JsdWUnKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGdndGl0bGUoIkRpc3RyaWJ1dGlvbiBvZiBwcmV2aW91cyBmYWlsdXJlcyBpbiBzdHVkZW50IGRhdGEiKSArCiAgeGxhYigiRmFpbHVyZXMiKSArCiAgeWxhYigiRGlzdHJpYnV0aW9uIG9mIEZhaWx1cmVzIikrCiAgdGhlbWUocGxvdC50aXRsZT1lbGVtZW50X3RleHQoZmFjZT0iYm9sZCIpKQpgYGAKQWZmaWNoZXIgbGEgY29ycsOpbGF0aW9uIGVudHJlIGxlcyDDqWNoZWNzIGV0IGxlcyBub3Rlcy4KYGBge3J9CmNvcihzdHVkZW50JEczLCBzdHVkZW50JGZhaWx1cmVzKQpwbG90KHg9c3R1ZGVudCRmYWlsdXJlcywgeT1zdHVkZW50JEczLCB4bGFiID0gIkZhaWx1cmVzIiwgeWxhYiA9ICJSYW5rIiwgY29sID0gImJsdWUiKQpgYGAKCgojIyMgw4l0dWRlIGRlIGxhIHZhcmlhYmxlICoqKmFic2VuY2VzKioqCmBgYHtyfQphYnNlbmNlcz0gZ2dwbG90KGRhdGE9c3R1ZGVudCxhZXMoeD1hYnNlbmNlcywgeT1HMSwgY29sPXNleCkpK2dlb21fcG9pbnQoKStnZW9tX3Ntb290aChtZXRob2Q9ImxtIixzZT1GKStmYWNldF9ncmlkKH5zZXgpCmFic2VuY2VzCmBgYArDgCBwYXJ0aXIgZHUgZ3JhcGhpcXVlIGNpLWRlc3N1cywgbm91cyBwb3V2b25zIHZvaXIgY29tbWVudCBsJ2Fic2VuY2UgYWZmZWN0ZSBuw6lnYXRpdmVtZW50IGxlcyBwZXJmb3JtYW5jZXMgZGVzIGdhcsOnb25zLCBtYWlzIGwnYWJzZW5jZSBkZSBjb3VycyBuJ2EgcGFzIGQnaW1wYWN0IG7DqWdhdGlmIHN1ciBsZXMgcGVyZm9ybWFuY2VzIGRlcyBmaWxsZXMgZW4gY2xhc3NlLgoKCiMjIyDDiXR1ZGUgZGUgbGEgdmFyaWFibGUgKioqRzEqKioKYGBge3J9CnZhcihzdHVkZW50JEcxKQphZ2VzPSBnZ3Bsb3QoZGF0YT1zdHVkZW50LGFlcyh4PWFnZSwgZmlsbD1zZXgpKStnZW9tX2hpc3RvZ3JhbShiaW53aWR0aD0wLjUwKQphZ2VzCmBgYApDb21tZSBsZSBtb250cmUgY2xhaXJlbWVudCBsZSBncmFwaGlxdWUgY2ktZGVzc3VzLCBsYSBwbHVwYXJ0IGRlcyDDqXR1ZGlhbnRzIGRlIHBsdXMgZGUgMTggYW5zIHNvbnQgZGVzIMOpdHVkaWFudHMgZGUgc2V4ZSBtYXNjdWxpbiBjYXIgaWwgbid5IGEgcGFzIGQnw6l0dWRpYW50ZXMgZGUgcGx1cyBkZSAyMCBhbnMuCgoqKipHMSBwYXIgcmFwcG9ydCBhdSBzZXhlIGV0IMOgIGwnw6JnZSoqKgpgYGB7cn0KRzE9Z2dwbG90KGRhdGE9c3R1ZGVudCxhZXMoeD1hZ2UsIHk9RzEsIGNvbD1zZXgsIHNoYXBlPXNleCkpK2dlb21fcG9pbnQoKStnZW9tX3Ntb290aChtZXRob2Q9ImxtIixzZT1GKStmYWNldF9ncmlkKH5zZXgpCkcxCmBgYApOb3VzIHBvdXZvbnMgdm9pciBxdWUgbGVzIHBlcmZvcm1hbmNlcyBkZXMgZmlsbGVzIHMnYW3DqWxpb3JlbnQgYXZlYyBsJ8OiZ2UsIGNlcGVuZGFudCwgdW5lIGRpbWludXRpb24gZGVzIHBlcmZvcm1hbmNlcyBkZXMgZ2Fyw6dvbnMgZXQgbmV0dGVtZW50IHZpc2libGUgZGFucyBsZSBncmFwaGlxdWUgY2ktZGVzc3VzLgoKLS0tLS0tLS0tLS0tLS0gZzIKCgojIyAzLjIgQ2FsY3VsIGRlIGxhIG1hdHJpY2UgZGUgY29ycsOpbGF0aW9uIHBvdXIgbGVzIHZhcmlhYmxlcyBxdWFudGl0YXRpdmVzLgojIyMgQ2FydGUgdGhlcm1pcXVlIHBvdXIgbGEgbWF0cmljZSBkZSBjb3Jyw6lsYXRpb24KYGBge3J9Cm51bWVyaWNfZmVhdHVyZXMgPC0gRmlsdGVyKGlzLm51bWVyaWMsIHN0dWRlbnQpCgpsaWJyYXJ5KHBoZWF0bWFwKQpwaGVhdG1hcChjb3IobnVtZXJpY19mZWF0dXJlcykpCmBgYAoKQ29tbWUgbW9udHJlIGxhIGNhcnRlLCBsYSBjb3Jyw6lsYXRpb24gdmFyaWUgZW50cmUgMSBldCAtMS4gTGEgY291bGV1ciByb3VnZSBjb3JyZXNwb25kIMOgIGxhIGNvcnLDqWxhdGlvbiDDqWxldsOpZSBlbnRyZSBub3MgY2FyYWN0w6lyaXN0aXF1ZXMuCgpQYXIgZXhlbXBsZSA6IApDb3Jyw6lsYXRpb24gcG9zaXRpdmUgOiAqKipHMSoqKiBldCAqKipHMyoqKgpDb3Jyw6lsYXRpb24gbsOpZ2F0aXZlIDogbGVzICoqKmZhaWx1cmVzKioqIGV0IGxlICoqKnN0dWR5dGltZSoqKiBwcsOpc2VudGVudCB1bmUgY29ycsOpbGF0aW9uIG7DqWdhdGl2ZQoKCiMjIyBNYXRyaWNlIGRlIG51YWdlIGRlIHBvaW50cyBHMSBldCBHMwoKYGBge3J9CiNwbG90KHdpdGgoc3R1ZGVudCxHMiksIHdpdGgoc3R1ZGVudCxHMyksIHhsYWI9J0cxJywgeWxhYj0nRzMnKQpnZ3Bsb3Qoc3R1ZGVudCwgYWVzKHg9RzIseT1HMykpICsgZ2VvbV9wb2ludCgpICsgZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIsIHNlPUZBTFNFKQpgYGAKT24gcGV1dCByZW1hcnF1ZXIgbGUgRzMgcHLDqXNlbnRlIHVuZSBmb3J0ZSBjb3Jyw6lsYXRpb24gcG9zaXRpdmUgYXZlYyBsZSBHMi4KCiMjIyBSw6lncmVzc2lvbiBtdWx0aXBsZSBlbnRyZSBsYSB2YXJpYWJsZSBHMyBwYXIgcmFwcG9ydCDDoCBhZ2UgCmBgYHtyfQpnZ3Bsb3Qoc3R1ZGVudCxhZXMoeD1HMykpK2dlb21faGlzdG9ncmFtKGZpbGw9ImRhcmtibHVlIixjb2xvcj0iZGFya2JsdWUiLG5hLnJtPVRSVUUpKwogICAgbGFicyh0aXRsZT0iQ2xhc3NlbWVudCBkZXMgbm90ZXMgRzMgcGFyIHJhcHBvcnQgw6AgbCfDomdlIix5PSIiLHg9IiIpK2ZhY2V0X3dyYXAofmFnZSkrCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCgojIyA0IMOJdHVkZSBkZXMgcmVsYXRpb25zIGVudHJlIGxlcyB2YXJpYWJsZXMgY2F0w6lnb3JpZWxsZXMgZXQgcXVhbnRpdGF0aXZlcy4KIyMjIDQuMSBSZXByw6lzZW50ZXIgbGVzIGFzc29jaWF0aW9ucyBlbnRyZSBsZXMgdmFyaWFibGVzIHF1YW50aXRhdGl2ZXMgZXQgbGVzIHZhcmlhYmxlcyBjYXTDqWdvcmllbGxlcyAoQm94cGxvdHMsIEJhciBjaGFydHMgZm9yIG1lYW5zLCBTdGFja2VkIGJhciBjaGFydHMsIE11bHRpcGxlIGhpc3RvZ3JhbXMsIGV0Yy4pCgpgYGB7cn0KY29udGVuZ2VuY3kgPC0gdGFibGUoc3R1ZGVudCRHMyxzdHVkZW50JHNleCkKcHJpbnQoY29udGVuZ2VuY3kpCmBgYAoKQ29uc3VsdGF0aW9uIGRlIGxhIGTDqXBlbmRhbmNlIGF2ZWMgdW4gc3RhY2sgYmFyIGNoYXJ0LgpgYGB7cn0KZ2dwbG90KHN0dWRlbnQsYWVzKHg9RzMsZmlsbD1zZXgpKStnZW9tX2Jhcihwb3NpdGlvbj0ic3RhY2siKSt0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSsKICBsYWJzKHg9Ik5vdGUgKEczKSIseT0iU2V4Iix0aXRsZT0iTm90ZXMgZGVzIMOpbMOodmVzIHBhciBzZXhlIikKYGBgCgoKT24gZmFpdCBlbnN1aXRlIHVuZSBjb21wYXJhaXNvbiBhdmVjIGRlcyAlIHBvdXIgbWlldSByZXByZXNlbnRlciBsZSBncmFwaC4KCmBgYHtyfQpnZ3Bsb3Qoc3R1ZGVudCxhZXMoeD1HMyxmaWxsPXNleCkpK2dlb21fYmFyKHBvc2l0aW9uPSJmaWxsIikrdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkrCiAgbGFicyh4PSJOb3RlIChHMykiLHk9IlNleGUiLHRpdGxlPSJOb3RlcyBkZXMgw6lsw6h2ZXMgcGFyIHNleGUgZW4gJSIpCmBgYAoKCiMjIyA0LjIgRWZmZWN0dWVyIGRlcyB0ZXN0cyB0IHBvdXIgY29tcGFyZXIgcGFyIHBhaXJlIGxhIG1veWVubmUgZGUgY2VydGFpbmVzIHZhcmlhYmxlcyBxdWFudGl0YXRpdmVzIGVuIGZvbmN0aW9uIGRlcyBkZXV4IG5pdmVhdXggZGUgY2VydGFpbmVzIHZhcmlhYmxlcyBjYXTDqWdvcmllbGxlcyBiaW5haXJlcy4KCgpDcsOpZXIgdW4gZW5zZW1ibGUgZGUgZG9ubsOpZXMgY29uc3RpdHXDqSB1bmlxdWVtZW50IGRlIGRvbm7DqWVzIG1hdGjDqW1hdGlxdWVzLCBhdmVjIGRlcyB2YXJpYWJsZXMgc2V4ZSAoKioqc2V4KioqKSBldCBub3RlIGZpbmFsZSgqKipHMyoqKi4KCmBgYHtyfQpkYXRhU2V4RzMgPSBzdWJzZXQoc3R1ZGVudCwgc2VsZWN0ID0gYyhzZXgsIEczKSkKZ2xpbXBzZShkYXRhU2V4RzMpCmBgYApOb3VzIGF2b25zIGRvbmMgdW5lIHZhcmlhYmxlIGNhdMOpZ29yaWVsbGUgcXVpIGVzdCBsZSAqKipzZXgqKiouIEV0IG5vdXMgYXZvbnMgdW5lIHZhcmlhYmxlIHF1YW50aXRhdGl2ZSBxdWkgZXN0ICoqKkczJCoqIChub3RlIGZpbmFsKQoKCkhpc3RvZ3JhbXMvYmFycGxvdCBkZXMgZGlmZsOpcmVudGVzIHZhcmlhYmxlcyBxdWkgc2Vyb250IHBlcnRpbmVudGVzIHBvdXIgbGVzIHRlc3RzIHN0YXRpc3RpcXVlcy4gCmBgYHtyfQpzZXhHcmFwaCA8LSB0YWJsZShkYXRhU2V4RzMkc2V4KQoKcGFyKG1mcm93PWMoMiwyKSkKaGlzdChkYXRhU2V4RzMkRzMsIGJyZWFrcyA9IDMwLCBjb2wgPSAiZGFya2JsdWUiLCBtYWluID0gIkhpc3RvZ3JhbSBkZSBsYSB2YXJpYWJsZSBzdHVkZW50IikKYmFycGxvdChzZXhHcmFwaCwgY29sPSJkYXJrYmx1ZSIsIG1haW4gPSAiQmFycGxvdCBkZSBsYSB2YXJpYWJsZSBzZXgiKQpgYGAKCgpHcmFwaGlxdWVzIGRlIGRlbnNpdMOpIHBvdXIgbCfDomdlLCBsZXMgYWJzZW5jZXMgZXQgbGUgbm90ZSBmaW5hbGUKYGBge3J9CkczRGVucyA8LSBkZW5zaXR5KGRhdGFTZXhHMyRHMykKcGxvdChHM0RlbnMpCmBgYAoKTm91cyBwb3V2b25zIHZvaXIgcXVlbHF1ZXMgdGVuZGFuY2VzIGNsYWlyZXMgZGFucyBsZXMgZG9ubsOpZXMuSWwgeSBhIHNldWxlbWVudCB1biBwZXUgcGx1cyBkZSBmZW1tZXMgcXVlIGQnaG9tbWVzLCBldCBsYSBub3RlIGZpbmFsZSBlbiBtYXRow6ltYXRpcXVlcyBlc3Qgw6AgcGV1IHByw6hzIMOpZ2FsZW1lbnQgcsOpcGFydGllLmxlIHBsdXMgZ3JhbmQgbm9tYnJlIGRlIHBlcnNvbm5lcyBxdWkgb250IMOpY2hvdcOpIGF1eCB0ZXN0cywgYydlc3Qtw6AtZGlyZSBxdWkgb250IHJlw6d1IGxhIG5vdGUgMCwgZmVyYSBwZW5jaGVyIHRvdXRlIGFuYWx5c2UgZGVzIG1veWVubmVzIGRlcyBub3RlcyBmaW5hbGVzIG5ldHRlbWVudCB2ZXJzIGxhIGdhdWNoZS4gQ2VsYSBlc3QgYXNzZXogw6l2aWRlbnQgc2kgbCdvbiByZWdhcmRlIGxlIGdyYXBoaXF1ZSBkZSBkZW5zaXTDqSBjaS1kZXNzdXMuIAoKCiMjIyA0LjIgRWZmZWN0dWVyIGRlcyB0ZXN0cyBwb3VyIGNvbXBhcmVyIHBhciBwYWlyZSBsYSBtb3llbm5lIGRlIGNlcnRhaW5lcyB2YXJpYWJsZXMgcXVhbnRpdGF0aXZlcyBlbiBmb25jdGlvbiBkZXMgZGV1eCBuaXZlYXV4IGRlIGNlcnRhaW5lcyB2YXJpYWJsZXMgY2F0w6lnb3JpZWxsZXMgYmluYWlyZXMuCgoKKioqTGUgdGVzdCBkZSBCYXJ0bGV0dCoqKgpgYGB7cn0KYmFydGxldHQudGVzdChHM1tkYXRhU2V4RzMkRzMgPiAwXSB+IHNleFtkYXRhU2V4RzMkRzMgPiAwXSwgZGF0YT1kYXRhU2V4RzMpCmBgYAoKCioqKkxlIHRlc3QgZGUgTGV2ZW5lKioqCmBgYHtyfQpsZXZlbmVUZXN0KHkgPSBkYXRhU2V4RzMkRzMsIGdyb3VwID0gZGF0YVNleEczJHNleCkKYGBgCgoKKioqVmlzdWFsaXNhdGlvbiBwYXIgQm94cGxvdCBkZXMgbm90ZXMgZmluYWxlcyBwb3VyIGNoYXF1ZSBzZXhlLioqKgpgYGB7cn0KZ2dwbG90KGRhdGFTZXhHMywgYWVzKHggPSBzZXgsIHkgPSBHMykpICsKICAgICAgICBnZW9tX2JveHBsb3QoY29sID0gImJsYWNrIikgKwogICAgICAgIGdndGl0bGUoIk1veWVubmVzIGRlcyBub3RlcyBmaW5hbGVzIHBhciBzZXhlIikKYGBgCgoKRW4gc2UgYmFzYW50IHN1ciBsZXMgZGV1eCB0ZXN0cyBldCBsYSB2aXN1YWxpc2F0aW9uIGRlcyBkb25uw6llcyBlbiBxdWVzdGlvbiwgb24gcGV1dCBhZmZpcm1lciBzYW5zIHJpc3F1ZSBxdWUgbCdoeXBvdGjDqHNlIGQnaG9tb2fDqW7DqWl0w6kgZGUgbGEgdmFyaWFuY2UgZXN0IHJlbXBsaWUgZGFucyBjZXQgZXhlbXBsZS4KCipMJ2hvbW9nw6luw6lpdMOpIGRlcyB2YXJpYW5jZXMgdC50ZXN0KgpgYGB7cn0KdC50ZXN0KGRhdGFTZXhHMyRHM1tkYXRhU2V4RzMkc2V4PT0iRiIgJiBkYXRhU2V4RzMkRzM+MF0sIGRhdGFTZXhHMyRHM1tkYXRhU2V4RzMkc2V4PT0iTSIgJiBkYXRhU2V4RzMkRzM+MF0pCmBgYAoKTGVzIG5vdGVzIGZpbmFsZXMgbW95ZW5uZXMgZGVzIGZpbGxlcyBldCBkZXMgZ2Fyw6dvbnMgc29udCBwcsOpc2VudMOpZXMgZGFucyBsYSBjb25zb2xlIGFwcsOocyBhdm9pciBlZmZlY3R1w6kgbGUgdGVzdCB0LiBMZXMgZmlsbGVzIG9udCBvYnRlbnUgdW5lIG5vdGUgZGUgMTEsMjAsIGV0IGxlcyBnYXLDp29ucyB1bmUgbm90ZSBtb3llbm5lIGRlIDExLDg2LiBDZXR0ZSBkaWZmw6lyZW5jZSBlc3Qgw6lnYWxlIMOgIGVudmlyb24gMCw2Ni4KCiMjIyA0LjMgQU5PVkEgcG91ciB0cm91dmVyIGxhIGRpZmbDqXJlbmNlIGVudHJlIGwnw6JnZSBldCBsZXMgbm90ZXMKYGBge3J9CmFnZS5nMyA8LSBhb3YoRzMgfiBmYWN0b3IoYWdlKSwgZGF0YSA9IHN0dWRlbnQpClR1a2V5SFNEKGFnZS5nMykKYGBgCgpMZXMgcsOpc3VsdGF0cyBtb250cmVudCBxdSdpbCBuJ3kgYSBwYXMgZGUgZGlmZsOpcmVuY2UgZGFucyBsZXMgbm90ZXMgZmluYWxlcyBlbnRyZSBsZXMgZGlmZsOpcmVudHMgZ3JvdXBlcyBkJ8OiZ2UuIExlcyB2YWxldXJzIHAgQWRqIHNvbnQgdG91dGVzIHN1cMOpcmlldXJlcyDDoCAwLDA1LgoKCiMgNSBDbHVzdGVyaW5nCiMjIDUuMSBLLW1veWVubmVzCgpQcmVwYXJpb24gZGUgbGEgZG9ubsOpCmBgYHtyfQojIG5vbWJyZSBkZSBsaWduZQpuYmwgPC0gNDAKIyBjcmVhdGlvbiBkdSBkYXRhIGZyYW1lCmtkZiA8LSBkYXRhLmZyYW1lKG1wcmJpZyRhZ2UsbXByYmlnJHN0dWR5dGltZSxtcHJiaWckZmFpbHVyZXMsbXByYmlnJGFic2VuY2VzLG1wcmJpZyRHMSxtcHJiaWckRzIsbXByYmlnJEczKQojc2NhbGluZyB0aGUgZGF0YQprZGYgPC0gc2NhbGUoa2RmWzA6bmJsLF0pCmBgYApEw6lzaWduYXRpb24gZHUgbWVpbGxldXIgbm9tYnJlIGRlIGNsdXN0ZXJzCmBgYHtyfQojQXZlcmFnZSBTaWxob3VldHRlIE1ldGhvZApmdml6X25iY2x1c3Qoa2RmLCBrbWVhbnMsIG1ldGhvZCA9ICJzaWxob3VldHRlIikKI0dhcCBTdGF0aXN0aWMgTWV0aG9kIChtZXRob2RlIHBvdXIgc2F2b2lyIGxlIG5vbWJyZSBkZSBjbHVzdGVyKQpnYXBfc3RhdCA8LSBjbHVzR2FwKGtkZiwgRlVOID0ga21lYW5zLCBuc3RhcnQgPSAyNSwgSy5tYXggPSAxMCkKZnZpel9nYXBfc3RhdChnYXBfc3RhdCkKYGBgCgpWaXN1YWxpc2F0aW9uIGRlcyBjbHVzdGVycwpgYGB7cn0Ka3JiaWcgPC0ga21lYW5zKGtkZiwgY2VudGVycyA9IDIsIG5zdGFydCA9IDUwKQpmdml6X2NsdXN0ZXIoa3JiaWcsIGRhdGEgPSBrZGYpCmBgYApBbmxhbGlzZSBkZXMgY2x1c3RlcnMKYGBge3J9CmZrcmJpZyA8LSBjYmluZChtcHJiaWdbMDpuYmwsXSwgY2x1c3Rlck51bSA9IGtyYmlnJGNsdXN0ZXIpCmdncGxvdChma3JiaWcsIGFlcyh4ID0gY2x1c3Rlck51bSwgeSA9IEczKSkgKyAKICBnZW9tX2JveHBsb3QoYWVzKGdyb3VwID0gY2x1c3Rlck51bSkpICsgCiAgc3RhdF9zdW1tYXJ5KGZ1biA9ICJtZWFuIiwgZ2VvbSA9ICJwb2ludCIsIHNpemU9IDIpICsKICBnZ3RpdGxlKCJOb3RlIHBhciByYXBwb3J0IGF1IGNsdXN0ZXIiKQpgYGAKRGFucyBsZSBsZSBncmFwaGlxdWUgY2ktZGVzc3VzLCBub3VzIHBvdXZvbnMgb2JzZXJ2ZXIgcXVlIGxlIHByZW1pZXIgY2x1c3RlciBtb250cmUgY2V1eCBxdWkgb250IHJldXNzaSBldCBkYW5zIGxlIGRldXhpw6ltZSBjbHVzdGVyIGNldXggcXVpIG4nb250IHBhcyByw6l1c3NpLgoKT24gcmVtYXJxdWUgcXVlIGxlcyBjbHVzdGVyIHNlIGZvbnQgcGFyIHJhcHBvcnQgYXUgbm90ZSAsIG9uIHBldXggZW4gZMOpZHVpcmUgcXVlIGxlcyB2YXJpYWJsZXMgdXRpbGlzw6llcyBuJ29udCBwYXMgZCdpbmZsdWVuY2Ugc3VyIGxlcyBub3RlcyAKCiMjIDUuMiBSZWdyb3VwZW1lbnQgaGnDqXJhcmNoaXF1ZQpWaXN1YWxpc2F0aW9uIGR1IFJlZ3JvdXBlbWVudCBoacOpcmFyY2hpcXVlCmBgYHtyfQojbm9tYnJlIGRlIGxpZ25lCm5ibCA8LSA0MAojY3JlYXRpb24gZHUgZGF0YSBmcmFtZQpoZGYgPC0gZGF0YS5mcmFtZShtcHJiaWckYWdlLG1wcmJpZyRzdHVkeXRpbWUsbXByYmlnJGZhaWx1cmVzLG1wcmJpZyRhYnNlbmNlcyxtcHJiaWckRzEsbXByYmlnJEcyLG1wcmJpZyRHMykKIyBsYSBtYXRyaWNlIGRlIGRpc3RhbmNlCmRpc3RtYXQgPC0gZGlzdChoZGZbMDpuYmwsXSxtZXRob2QgPSAnZXVjbGlkZWFuJykKaHJiaWcgPC0gaGNsdXN0KGRpc3RtYXQpCnBsb3QoaHJiaWcpCmBgYApPbiByZW1hcnF1ZSBiaWVuIHF1J2lsIHkgYSBkZXV4IGdyYW5kZSBwYXJ0aWUKCkTDqWNvdXBlIGRlIGwnYXJicmUgZW4gY2x1c3RlcnMKYGBge3J9CiNkZWNvdXBlIGRlIGwnYXJicmUgZW4gY2x1c3RlcgpjdXQgPC0gY3V0cmVlKGhyYmlnLDIpCnBsb3QoaHJiaWcpCnJlY3QuaGNsdXN0KGhyYmlnICwgayA9IDIsIGJvcmRlciA9IDI6NikKYGBgCkFuYWxpc2UgZGVzIGRvbm5lciBkYW5zIGNoYXF1ZSBjbHVzdGVycwpgYGB7cn0KZmhyYmlnIDwtIGNiaW5kKG1wcmJpZ1swOm5ibCxdLCBjbHVzdGVyTnVtID0gY3V0KQpnZ3Bsb3QoZmhyYmlnLCBhZXMoeCA9IGNsdXN0ZXJOdW0sIHkgPSBHMykpICsgCiAgZ2VvbV9ib3hwbG90KGFlcyhncm91cCA9IGNsdXN0ZXJOdW0pKSArIAogIHN0YXRfc3VtbWFyeShmdW4gPSAibWVhbiIsIGdlb20gPSAicG9pbnQiLCBzaXplPSAyKSArCiAgZ2d0aXRsZSgiTm90ZSBwYXIgcmFwcG9ydCBhdSBjbHVzdGVyIikKYGBgCk9uIHJlbWFycXVlIHF1ZSBjJ2VzdCBsYSBtZW1lIGRpc3Bvc2l0aW9uIHF1J2F2ZWMgbGUgay1tb3llbm5lIG1haXMgbGVzIGNsdXN0ZXIgc29udCBpbnZlcnPDqXMgOiAgZGFucyBsZSBwcmVtaWVyIG5vdXMgYXZvbnMgbGVzIG1vaW5zIGJvbm5lIG5vdGVzIGV0IGRhbnMgbGUgMmllbWUgbGVzIG1laWxsZXVycyBub3RlcwoKT24gcmVtYXJxdWUgbGVzIG3Dqm1lcyBjbHVzdGVycyBxdWUgbGUgay1tb3llbm5lLCBvbiBwZXV4IGRpcmUgcXVlIGxlcyB2YXJpYWJsZSB1dGlsaXPDqSBuJ29udCBwYXMgZCdpbmZsdWVuY2Ugc3VyIGxlcyBub3RlcwoKIyMgNiBDb25sdXNpb24KClN1aXRlIMOgIGwnw6l0dWRlIHF1ZSBub3VzIGF2b25zIG1lbsOpIHN1ciBsZXMgZG9ubsOpZXMgZHUgZmljaGllciBDU1YvWExYUywgbm91cyBwb3V2b25zIGNvbmNsdXJlIHF1ZSBsZSBmYWN0ZXVyIHF1aSBpbmZsdWUgbGUgcGx1cyBzdXIgbGEgbm90YXRpb24gZGVzIMOpdHVkaWFudHMgZXN0IGxlIGdlbnJlLiBFbiBlZmZldCwgbm91cyBhdm9ucyBjb25zdGF0w6kgcXVlIGxlcyBmaWxsZXMgc29udCBiZWF1Y291cCBwbHVzIG1vdGl2w6llIMOgIGwnaWTDqWUgZGUgcG91cnN1aXZyZSBkZXMgw6l0dWRlcyBzdXDDqXJpZXVyZXMgZXQgb250IHBsdXMgZGUgc3VwcG9ydCBww6lkYWdvZ2lxdWUgcXVlIGxlcyBnYXLDp29ucyhzdXBwb3J0IGRlIGNvdXJzIHBlcnNvbm5lbCBzdXBwbMOpbWVudGFpcmUpLgoKUG91ciBsZXMgZ2Fyw6dvbnMsIGlscyBzb250IHBsdXMgw6Jnw6lzLCDDqXR1ZGllbnQgbW9pbnMgZXQgb250IHBsdXMgZCdhYnNlbmNlcyBxdWUgbGVzIGZpbGxlcy4gQ2VsYSBlbnRyYcOubmUgdW4gcmV0YXJkIHF1J2lscyBuJ2Fycml2ZW50IHBhcyDDoCByYXR0cmFwZXIgcGFyIGxhIHN1aXRlLgoKQ2UgcXVpIHBlcm1ldCBkb25jIGQnYWZmaXJtZXIgcXVlIGxlcyBmaWxsZXMgcydlbiBtaWV1eCBxdWUgbGVzIGdhcsOnb25zIGRhbnMgbGV1cnMgw6l0dWRlcyBkZSBtYW5pw6hyZSBnw6luw6lyYWxlLg==